Fix SMP_ALTERNATIVES to cope with discarded init data.
authorsos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Wed, 6 Jul 2005 18:33:27 +0000 (18:33 +0000)
committersos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Wed, 6 Jul 2005 18:33:27 +0000 (18:33 +0000)
Signed-off-by: steven.smith@cl.cam.ac.uk
patches/linux-2.6.11/smp-alts.patch

index db71ab1e56f8de6d54a7d19deec7b551e274041a..5d18c5e71a75a59c8d5e7e2f141b1c2770973b3f 100644 (file)
@@ -35,7 +35,7 @@ diff -Naur linux-2.6.11/arch/i386/kernel/Makefile linux-2.6.11.post/arch/i386/ke
 diff -Naur linux-2.6.11/arch/i386/kernel/smpalts.c linux-2.6.11.post/arch/i386/kernel/smpalts.c
 --- linux-2.6.11/arch/i386/kernel/smpalts.c    1970-01-01 01:00:00.000000000 +0100
 +++ linux-2.6.11.post/arch/i386/kernel/smpalts.c       2005-06-16 11:23:39.300902424 +0100
-@@ -0,0 +1,76 @@
+@@ -0,0 +1,85 @@
 +#include <linux/kernel.h>
 +#include <asm/system.h>
 +#include <asm/smp_alt.h>
@@ -58,6 +58,7 @@ diff -Naur linux-2.6.11/arch/i386/kernel/smpalts.c linux-2.6.11.post/arch/i386/k
 +
 +extern struct smp_alternative_record __start_smp_alternatives_table,
 +  __stop_smp_alternatives_table;
++extern unsigned long __init_begin, __init_end;
 +
 +void prepare_for_smp(void)
 +{
@@ -69,6 +70,10 @@ diff -Naur linux-2.6.11/arch/i386/kernel/smpalts.c linux-2.6.11.post/arch/i386/k
 +              BUG_ON(r->repl->targ_size < r->repl->smp1_size);
 +              BUG_ON(r->repl->targ_size < r->repl->smp2_size);
 +              BUG_ON(r->repl->targ_size < r->repl->up_size);
++               if (system_state == SYSTEM_RUNNING &&
++                   r->targ_start >= (void *)&__init_begin &&
++                   r->targ_start < (void *)&__init_end)
++                       continue;
 +              if (r->repl->feature != (unsigned char)-1 &&
 +                  boot_cpu_has(r->repl->feature)) {
 +                      memcpy(r->targ_start,
@@ -101,6 +106,10 @@ diff -Naur linux-2.6.11/arch/i386/kernel/smpalts.c linux-2.6.11.post/arch/i386/k
 +              BUG_ON(r->repl->targ_size < r->repl->smp1_size);
 +              BUG_ON(r->repl->targ_size < r->repl->smp2_size);
 +              BUG_ON(r->repl->targ_size < r->repl->up_size);
++               if (system_state == SYSTEM_RUNNING &&
++                   r->targ_start >= (void *)&__init_begin &&
++                   r->targ_start < (void *)&__init_end)
++                       continue;
 +              memcpy(r->targ_start,
 +                     r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
 +                     r->repl->up_size);